package com.hy.str;

public class ReserveStr {

    /**
     * 344.反转字符串
     * 力扣题目链接
     *
     * 编写一个函数，其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
     *
     * 不要给另外的数组分配额外的空间，你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
     *
     * 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
     *
     * 示例 1：
     * 输入：["h","e","l","l","o"]
     * 输出：["o","l","l","e","h"]
     *
     * 思路
     * 如果题目关键的部分直接用库函数就可以解决，建议不要使用库函数。
     * 如果库函数仅仅是 解题过程中的一小部分，并且你已经很清楚这个库函数的内部实现原理的话，可以考虑使用库函数。
     *
     * 大家应该还记得，我们已经讲过了206.反转链表。
     *
     * 在反转链表中，使用了双指针的方法。
     *
     * 那么反转字符串依然是使用双指针的方法，只不过对于字符串的反转，其实要比链表简单一些。
     * 因为字符串也是一种数组，所以元素在内存中是连续分布，这就决定了反转链表和反转字符串方式上还是有所差异的。
     *
     * 循环里只要做交换s[i] 和s[j]操作就可以了，那么我这里使用了swap 这个库函数。
     * swap可以有两种实现。
     * 一种就是常见的交换数值：
     *  int tmp = s[i];
     *  s[i] = s[j];
     *  s[j] = tmp;
     *  一种就是通过位运算：
     *  s[i] ^= s[j];
     *  s[j] ^= s[i];
     *  s[i] ^= s[j];
     */
    // 位运算
    public static void reverseString(char [] s){
        int left = 0;
        int right = s.length - 1;

        while (left < right){
            //构造 a ^ b 的结果，并放在 a 中
            s[left] ^= s[right];
            s[right] ^= s[left];
            s[left] ^= s[right];
            left++;
            right--;
        }
        System.out.println("res: "+ new String(s));
    }

    // 数值交换
    public static void reverseString2(char [] s){
        int left = 0;
        int right = s.length - 1;
        while (left < right){
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
        System.out.println("res2: "+ new String(s));
    }


    public static void main(String[] args) {
        String c = "hello";

        reverseString(c.toCharArray());
        reverseString2(c.toCharArray());
    }
}
